package com.system.registrationPool.service.impl;

import com.system.registrationPool.bean.Arrangement;
import com.system.registrationPool.bean.Employee;
import com.system.registrationPool.bean.RegistrationPoolList;
import com.system.registrationPool.feign.ArrangementServiceFeign;
import com.system.registrationPool.feign.EmployeeServiceFeign;
import com.system.registrationPool.repository.RegistrationPoolListRepository;
import com.system.registrationPool.repository.RegistrationPoolRepository;
import com.system.registrationPool.service.RegistrationPoolListService;
import com.system.registrationPool.vo.ConfirmInfoVO;
import com.system.registrationPool.vo.RegistrationPoolLstVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 林
 */
@Service
public class RegistrationPoolListServiceImpl implements RegistrationPoolListService {
    @Autowired
    private RegistrationPoolListRepository registrationPoolListRepository;

    @Autowired
    private RegistrationPoolRepository registrationPoolRepository;

    @Autowired
    private ArrangementServiceFeign arrangementServiceFeign;

    @Autowired
    private EmployeeServiceFeign employeeServiceFeign;

    @Override
    public boolean saveRegistrationPoolList(RegistrationPoolList registrationPoolList) {
        RegistrationPoolList obj = registrationPoolListRepository.save(registrationPoolList);
        if (obj != null) {
            return true;
        }
        return false;
    }

    @Override
    public boolean removeRegistrationPoolListById(int id) {
        if (registrationPoolListRepository.existsById(id)) {
            registrationPoolListRepository.deleteById(id);
            return true;
        }
        return false;
    }

    @Override
    public boolean modifyRegistrationPoolList(RegistrationPoolList registrationPoolList) {
        RegistrationPoolList obj = registrationPoolListRepository.save(registrationPoolList);
        if (obj != null) {
            return true;
        }
        return false;
    }

    @Override
    public RegistrationPoolList getRegistrationPoolListById(int id) {
        if (registrationPoolListRepository.existsById(id)) {
            return registrationPoolListRepository.getReferenceById(id);
        }
        return null;
    }

    @Override
    public List<RegistrationPoolList> listAllRegistrationPoolLists() {
        return registrationPoolListRepository.findAll();
    }

    @Override
    public List<RegistrationPoolList> findAllByPoolId(int poolId) {
        return registrationPoolListRepository.findAllByPoolId(poolId);
    }

    @Override
    public List<RegistrationPoolList> findAllByArrangementId(int arrangementId) {
        return registrationPoolListRepository.findAllByArrangementId(arrangementId);
    }

    @Override
    public List<RegistrationPoolLstVO> findVoByArrangementId(int arrangementId) {
        List<RegistrationPoolList> registrationPoolLists = findAllByArrangementId(arrangementId);
        List<RegistrationPoolLstVO> registrationPoolLstVOS = new ArrayList<>();
        for (RegistrationPoolList registrationPoolList : registrationPoolLists) {
            RegistrationPoolLstVO registrationPoolLstVO = new RegistrationPoolLstVO();
            registrationPoolLstVO.setPoolListId(registrationPoolList.getPoolListId());
            registrationPoolLstVO.setRegistrationNum(registrationPoolList.getRegistrationNum() + registrationPoolList.getAddNum());
            registrationPoolLstVO.setRegistrationPrice(registrationPoolList.getRegistrationPrice());
            registrationPoolLstVO.setLockNum(registrationPoolList.getLockNum());
            registrationPoolLstVO.setBgnTm(registrationPoolList.getBgnTm());
            registrationPoolLstVO.setEndTm(registrationPoolList.getEndTm());
            registrationPoolLstVOS.add(registrationPoolLstVO);
        }
        return registrationPoolLstVOS;
    }

    @Override
    public Integer findNumByArrangementId(int arrangementId) {
        List<RegistrationPoolList> registrationPoolLists = findAllByArrangementId(arrangementId);
        int num = 0;
        for (RegistrationPoolList registrationPoolList : registrationPoolLists) {
            num += registrationPoolList.getAddNum() + registrationPoolList.getRegistrationNum();
        }
        return num;
    }

    @Override
    public Integer findLockNumByArrangementId(int arrangementId) {
        List<RegistrationPoolList> registrationPoolLists = findAllByArrangementId(arrangementId);
        int num = 0;
        for (RegistrationPoolList registrationPoolList : registrationPoolLists) {
            num += registrationPoolList.getLockNum();
        }
        return num;
    }

    @Override
    public boolean lockNumber(Integer poolListId) {
        RegistrationPoolList registrationPoolList = registrationPoolListRepository.findById(poolListId)
                .orElseThrow(() -> new IllegalArgumentException("Invalid poolListId: " + poolListId));

        if (registrationPoolList.getAddNum() == null)
            registrationPoolList.setAddNum(0);
        if (registrationPoolList.getLockNum() == null)
            registrationPoolList.setLockNum(0);

        int totalAvailable = registrationPoolList.getRegistrationNum() + registrationPoolList.getAddNum() - registrationPoolList.getLockNum();
        if (totalAvailable <= 0) {
            System.out.println("Cannot lock number. No available slots.");
            return false;
        }

        int lockNum = registrationPoolList.getLockNum() + 1;
        registrationPoolList.setLockNum(lockNum);
        if (registrationPoolListRepository.save(registrationPoolList).getLockNum() == lockNum)
            return true;
        return false;
    }

    @Override
    public boolean releaseNumber(Integer poolListId) {
        RegistrationPoolList registrationPoolList = registrationPoolListRepository.findById(poolListId)
                .orElseThrow(() -> new IllegalArgumentException("Invalid poolListId: " + poolListId));

        if (registrationPoolList.getAddNum() == null)
            registrationPoolList.setAddNum(0);
        if (registrationPoolList.getLockNum() == null)
            registrationPoolList.setLockNum(0);

        int lockNum = registrationPoolList.getLockNum() - 1;
        registrationPoolList.setLockNum(lockNum);
        if (registrationPoolListRepository.save(registrationPoolList).getLockNum() == lockNum)
            return true;
        return false;
    }

    @Override
    public String getTime(Integer poolListId) {
        if (registrationPoolListRepository.existsById(poolListId)) {
            RegistrationPoolList registrationPoolList = registrationPoolListRepository.getReferenceById(poolListId);
            return registrationPoolRepository.getReferenceById(registrationPoolList.getPoolId()).getPoolDt() + " " + registrationPoolList.getBgnTm() + "-" + registrationPoolList.getEndTm();
        }
        return null;
    }

    @Override
    public Integer getArrangementId(Integer poolListId) {
        if (registrationPoolListRepository.existsById(poolListId)) {
            RegistrationPoolList registrationPoolList = registrationPoolListRepository.getReferenceById(poolListId);
            return registrationPoolList.getArrangementId();
        }
        return null;
    }

    @Override
    public ConfirmInfoVO getDoctorInfo(Integer poolListId) {
        if (registrationPoolListRepository.existsById(poolListId)) {
            RegistrationPoolList registrationPoolList = registrationPoolListRepository.getReferenceById(poolListId);
            ConfirmInfoVO confirmInfoVO = new ConfirmInfoVO();
            confirmInfoVO.setAppointmentData(String.valueOf(registrationPoolRepository.getReferenceById(registrationPoolList.getPoolId()).getPoolDt()));
            confirmInfoVO.setAppointmentTime(registrationPoolList.getBgnTm() + "-" + registrationPoolList.getEndTm());
            confirmInfoVO.setServiceFee("￥" + String.valueOf(registrationPoolList.getRegistrationPrice()));
            Arrangement arrangement = arrangementServiceFeign.getHandle(registrationPoolList.getArrangementId());
            Employee employee = employeeServiceFeign.getHandle(arrangement.getEmployeeId());

            confirmInfoVO.setDoctorName(employee.getEName());
            confirmInfoVO.setDoctorLabel(employee.getETitle());
            return confirmInfoVO;
        }
        return null;
    }
}
